﻿using System;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
using NazTek.Utility;

namespace NazTek.Archive.Control.Entity
{
    /// <summary>
    /// Encapsulates database server specific configuration information for archiving.
    /// </summary>
    [Serializable]
    public sealed class ServerMetadata
    {
        /// <summary>
        /// Gets/sets server name.
        /// </summary>
        public string ServerName { get; set; }
        /// <summary>
        /// Gets/sets database server instance.
        /// </summary>
        public string Instance { get; set; }
        /// <summary>
        /// Gets/sets list of database information for archiving.
        /// </summary>
        public List<DatabaseMetadata> DatabaseList { get; set; }
        /// <summary>
        /// Publishes notification.
        /// </summary>
        internal event EventHandler<NoticeEventArgs> Notice;
        /// <summary>
        /// Executes <see cref="DatabaseMetadata.Archive"/> for each database specified within the database server.
        /// </summary>
        internal void Archive()
        {
            Notify(string.Format("Archiving server: {0}", NameWithInstance));
            DatabaseServer = new Server(NameWithInstance);
            DatabaseList.ForEach(database =>
            {
                database.Notice += (sender, eventArgs) => Notify(eventArgs.Message);
                database.Archive(this);
            });
        }
        /// <summary>
        /// Gets target archive database instance, creating it if necessary within the source server instance.
        /// </summary>
        /// <param name="archiveDatabaseName">Name of the archive database to fetch.</param>
        /// <returns>Archive database instance.</returns>
        internal Database EnsureArchiveDatabase(string archiveDatabaseName)
        {
            if (DatabaseServer.Databases.Contains(archiveDatabaseName)) 
                return DatabaseServer.Databases[archiveDatabaseName];
            Notify(string.Format("Creating archive database: [{0}]", archiveDatabaseName));
            new Database(DatabaseServer, archiveDatabaseName).Create();
            return DatabaseServer.Databases[archiveDatabaseName];
        }
        /// <summary>
        /// Gets/sets database server, for both source and destination for the archive.
        /// </summary>
        internal Server DatabaseServer { get; set; }
        /// <summary>
        /// Gets database server name, with instance when available.
        /// </summary>
        private string NameWithInstance
        {
            get { return Instance == null ? ServerName : string.Format(@"{0}\{1}", ServerName, Instance); }
        }
        /// <summary>
        /// Publishes notification, when there are active subscribers.
        /// </summary>
        /// <param name="message">Message to publish.</param>
        private void Notify(string message)
        {
            if (Notice != null)
                Notice(this, new NoticeEventArgs(message));
        }
    }
}